package feizhou.untils.tools;

import lombok.Data;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Arrays;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: IdGenerateTool
 * @Description 请描述下该类是做什么的
 * @Author feizhou
 * @Date 2023/3/10  10:38
 * @Verson 1.0
 **/

@Data
public class RedisUtil {

    private static RedisTemplate<String, Object> redisTemplate;

    static {
        if (redisTemplate == null) {
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
    }

    private static String uuidKeyPrefix = "uuidKeyPrefix";


    public static Boolean lock(String key, long expireTime) {
        String uuid = UUID.randomUUID().toString();
        String locKey = uuidKeyPrefix + key;

        // 过期时间是为了防止死锁
        Boolean lock = redisTemplate.opsForValue().setIfAbsent(locKey, uuid, expireTime, TimeUnit.MILLISECONDS);

        return lock;
    }

    public static void unlock(String locKey) {
        String uuidKey = uuidKeyPrefix + locKey;
        String uuid = (String) redisTemplate.opsForValue().get(uuidKey);

        // 使用lua脚本来保证释放锁的原子性
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";

        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        redisScript.setScriptText(script);
        redisScript.setResultType(Long.class);

        redisTemplate.execute(redisScript, Arrays.asList(locKey), uuid);

    }

    /**
     * 存储 hash对象
     *
     * @param key
     * @param hashKey
     * @param value
     * @return void
     * @author <a href="920786312@qq.com">周飞</a>
     * @since 2023/10/19 15:52
     */
    public static void hashSet(String key, String hashKey, Object value) {
        HashOperations<String, Object, Object> stringObjectObjectHashOperations = redisTemplate.opsForHash();
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    /**
     * 获取 hash对象
     *
     * @param key
     * @param hashKey
     * @return void
     * @author <a href="920786312@qq.com">周飞</a>
     * @since 2023/10/19 15:55
     */
    public static void hashGet(String key, String hashKey) {
        HashOperations<String, Object, Object> stringObjectObjectHashOperations = redisTemplate.opsForHash();
        redisTemplate.opsForHash().get(key, hashKey);
    }

    /**
     * 普通 set
     *
     * @param key
     * @param value
     * @return void
     * @author <a href="920786312@qq.com">周飞</a>
     * @since 2023/10/19 15:54
     */
    public static void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    /**
     * 普通 set
     *
     * @param key
     * @param value
     * @param expireTime 过期时间 单位毫秒
     * @return void
     * @author <a href="920786312@qq.com">周飞</a>
     * @since 2023/10/19 17:37
     */
    public static void set(String key, Object value, long expireTime) {
        redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.MILLISECONDS);
    }

    /**
     * 普通 get
     *
     * @param key
     * @return java.lang.Object
     * @author <a href="920786312@qq.com">周飞</a>
     * @since 2023/10/19 15:54
     */
    public static Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 删除  key
     *
     * @param key
     * @return java.lang.Boolean
     * @author <a href="920786312@qq.com">周飞</a>
     * @since 2023/10/19 17:40
     */
    public static Boolean delete(String key) {
        return redisTemplate.delete(key);
    }

    /**
     * 删除  keys
     * @param keys
     * @return java.lang.Boolean
     * @author <a href="920786312@qq.com">周飞</a>
     * @since 2023/10/19 17:40
     */
    public static Long delete(Collection<String> keys) {
        return redisTemplate.delete(keys);
    }

    public static void main(String[] args) {

    }
}

